/**
 * @file        gpio-stm32f4xx.c
 *
 * @brief       GPIO APIs for stm32F4xx uControllers
 *
 * @date        Nov 28, 2012 11:35:50 PM
 *
 * @author      Ashwin Vijayakumar
 *
 * @copyright   (C) 2012 Ashwin Vijayakumar <ashwin@afflatustech.com>
 * @copyright   (C) 2012 Afflatus Techtronics <www.afflatustech.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 */

/* ---- System headers ------------------------------------------------------ */
/* ---- Local headers ------------------------------------------------------- */
#include "gpio-stm32f4xx.h"
#include "stm32f4xx.h"

/* ---- Typedef section (lower_case_type) ----------------------------------- */
/* ---- Constants section (ALL_CAPS) ---------------------------------------- */
/* ---- Macros section (ALL_CAPS) ------------------------------------------- */
/* ---- Global variables section (lower_case) ------------------------------- */
/* ---- Function prototypes section (lower_case) ---------------------------- */
/* ---- Getter/setter method section (get/set/is_lower_case) ---------------- */

/**
 * @fn          gpio_stm32f4xx_direction_input
 */
void
gpio_stm32f4xx_direction_input( gpio_port_type* gpio_port, gpio_pin_type gpio_pin )
{
  uint32_t gpio_pin_num = 0;

  while( gpio_pin )
    {
      if(gpio_pin & 0x01)
        gpio_port->MODER &= ~( (uint32_t)0x03 << (gpio_pin_num * 2) );

      gpio_pin >>= 1;
      gpio_pin_num++;
    }
}

/**
 * @fn          gpio_stm32f4xx_direction_output
 */
void
gpio_stm32f4xx_direction_output( gpio_port_type* gpio_port, gpio_pin_type gpio_pin )
{
  uint32_t gpio_pin_num = 0;

  while( gpio_pin )
    {
      if(gpio_pin & 0x01)
        {
          gpio_port->MODER |= ( (uint32_t)0x01 << (gpio_pin_num * 2) );
          gpio_port->MODER &= ~( (uint32_t)0x02 << (gpio_pin_num * 2) );
        }

      gpio_pin >>= 1;
      gpio_pin_num++;
    }
}

/**
 * @fn          gpio_stm32f4xx_get_value
 */
int
gpio_stm32f4xx_get_value( gpio_port_type* gpio_port )
{
  return( (int)gpio_port->IDR );
}

/**
 * @fn          gpio_stm32f4xx_set_value
 */
void
gpio_stm32f4xx_set_value( gpio_port_type* gpio_port, uint32_t value )
{
  gpio_port->ODR = value;
}

/**
 * @fn          gpio_stm32f4xx_get_pin
 */
int
gpio_stm32f4xx_get_pin( gpio_port_type* gpio_port, gpio_pin_type gpio_pin )
{
  return( (int)(gpio_port->IDR & gpio_pin) );
}

/**
 * @fn          gpio_stm32fxx_set_pin
 */
void
gpio_stm32f4xx_set_pin( gpio_port_type* gpio_port, gpio_pin_type gpio_pin )
{
  gpio_port->BSRRL |= gpio_pin;
}

/**
 * @fn          gpio_stm32f4xx_reset_pin
 */
void
gpio_stm32f4xx_reset_pin( gpio_port_type* gpio_port, gpio_pin_type gpio_pin )
{
  gpio_port->BSRRH |= gpio_pin;
}

/**
 * @fn          gpio_stm32f4xx_toggle_pin
 */
void
gpio_stm32f4xx_toggle_pin( gpio_port_type* gpio_port, gpio_pin_type gpio_pin )
{
  gpio_port->ODR ^= gpio_pin;
}

/* ==== End of file ================= Copyright (C) 2012 Afflatus Techtronics */
